<template>
  <div class="calendarX">
    <el-calendar v-model="nowDate" v-bind="$attrs">

      <template #header="{date}">
        <slot name="header">

          <!-- region 头部插槽 -->
          <div class="headerBox">

            <!-- region 左侧 -->
            <div class="left">
              <slot name="left">
                1234
              </slot>
            </div>
            <!-- endregion -->

            <!-- region 中间 -->
            <div class="center">
              <slot name="center">
                center
              </slot>
            </div>
            <!-- endregion -->

            <!-- region 右侧 -->
            <div class="right">
              <slot name="right">
                right
              </slot>
            </div>
            <!-- endregion -->

          </div>
          <!-- endregion -->

        </slot>
      </template>

    </el-calendar>
  </div>
</template>

<script setup>
import { ElCalendar } from 'element-plus'
import { ref,watch } from 'vue'

const props = defineProps({
  modelValue: {
    type: [String, Number, Object],
    default: ''
  },

  // 右边按钮
  bnList: {
    type: Object,
    default: [
      {
        label: '按钮',
        click: (nowDate) => {

        }
      }
    ]
  },
})


const emit = defineEmits(['update:modelValue'])


// region 工具类

class ListUtil {

  // 遍历嵌套取值。根据field字段，在data中通过对比value。找到则返回该对象。根据children字段遍历下级列表
  async getChildren(data = [], value = '', toLower = false, field = 'id', children = 'children') {
    if (toLower && typeof value == 'string') {
      value = value.toLowerCase()
    }
    const haveData = await this.findChildren(data, (child) => {
      let childValue = child[field]
      if (toLower && typeof childValue == 'string') {
        childValue = childValue.toLowerCase()
      }
      if (childValue == value) {
        return true
      }
    }, children)
    return haveData
  }

  // 字符串或数组去重复元素
  removeSame(Obj) {
    if (typeof Obj === 'string') {
      const text = new Set(Obj)
      return [...text].join('')
    } else if (Obj instanceof Array) {
      return Array.from(new Set(Obj))
    } else {
      return Obj
    }
  }

  // 遍历嵌套取值。根据children字段遍历下级列表。返回当前子级对象
  async findChildren(data = [], callBack = undefined, children = "children") {
    let tempResult = undefined
    const findFn = async (ChildData, father) => {
      let isOk = false
      for (let item of ChildData) {
        if (typeof callBack == "function") {
          const isBreak = await callBack(item, father)
          if (isBreak == true) {
            tempResult = item
            isOk = true
            break;
          }
        }
        if (isOk) {
          tempResult = item
          return item
        }

        // 如果有下一级数据
        if (item[children] != undefined && item[children].length > 0) {
          let result = await findFn(item[children], item)
          if (result) {
            return true
          }
        }
      }
      return isOk;
    }
    await findFn(data, {})
    return tempResult
  }

  // 找到最上层父级，并将关联的放到一个列表中。
// callBack：(row：当前遍历到的对象,thisObj: 当前对比的父级)
// fatherKey：用来保存父级key对应值的。childkey:标记是最后一层
// 返回：[ [{id:'1},{id:'1-1'}], [{id:'1'},{id:'1-2'}] ]
  async getFather(data = [], childValue = undefined, callBack = undefined,
                  key = "id", toLower = true, childField = "children",
                  fatherKey = undefined, childKey = undefined) {
    if (data.length <= 0 || !(data instanceof Array)) {
      return []
    }
    let date = Date.now();
    let tempKey = `temp_father${date}`
    if (fatherKey != undefined) {
      tempKey = fatherKey
    }
    let tempChildKey = `temp_child${date}`
    if (childKey != undefined) {
      tempChildKey = childKey
    }
    // 改成一级列表，并重新赋值父级字段
    let tempList = this.unlockTree(data, key, childField, tempKey, false, tempChildKey)

    // 获取指定关联的方法
    async function _fn(newChildValue) {
      let tempResult = []
      // 每层的关联
      let secondList = []
      let tempObj = {[key]: newChildValue}
      while (true) {
        // 遍历获取判断对象
        let thisObj = undefined
        for (let i = 0; i < tempList.length; i++) {
          let row = tempList[i]
          let isOk = false
          // 自定义判断
          if (typeof callBack == 'function') {
            isOk = await callBack(row, tempObj)
          } else {
            isOk = stringUtil.equalStr(row[key], tempObj[key], toLower, toLower)
          }
          if (isOk) {
            thisObj = row
            // 如果是只获取指定值，那么移除已经获取到的数据，减少循环
            if (childValue != undefined) {
              tempList.splice(i, 1)
            }
            break;
          }
        }

        if (thisObj) {
          secondList.unshift(thisObj)
          // 获取它的父级id
          let fatherkey = thisObj[tempKey]
          if (fatherkey == undefined) {
            // 没有上一级了
            break;
          }
          tempObj[key] = fatherkey
        } else {
          break;
        }
      }
      tempResult.push(secondList)
      return tempResult
    }

    // 获取全部关联
    if (childValue == undefined) {
      // 先获取全部最后一级
      const childList = tempList.filter(item => item[tempChildKey] == true)
      // 开始处理子级数据
      let result = []
      for (let i = 0; i < childList.length; i++) {
        const tempResult = await _fn(childList[i][key])
        if (tempResult.length > 0) {
          result.push(tempResult[0])
        }
      }
      return result
    }
    // 获取指定关联
    else {
      return await _fn(childValue)
    }
  }

  // 创建树形结构数据。outList：提供要给列表变量参数，用来保存没有处理的数据
  async makeTreeAsync(dataList, outList = [], id = 'id', parent = {field: 'parentId', value: '-1'},
                      childField = 'children', sortField = 'sort') {
    let result = []
    let childList = [] // 临时保存子级

    // 处理父级
    dataList.forEach(item => {
      if (item[parent.field] == parent.value || item[parent.field] == undefined) {
        if (item[childField] == undefined) {
          item[childField] = []
        }
        result.push(item)
      } else {
        childList.push(item)
      }
    })
    if (dataList.length > 0 && dataList[0][sortField] != undefined) {
      dataList.sort((v1, v2) => v1[sortField] > v2[sortField] ? 1 : -1)
    }

    // 处理子级
    // 记录上一次子级列表的剩余的数据条数
    let lastLen = childList.length
    // 找不到父级的列表数据
    let tempList = []

    while (1) {
      // 这次循环剩余的子级列表
      tempList = []
      for (let i = 0; i < childList.length; i++) {
        let item = childList[i]
        // 找到这个item菜单所属的父级对象
        let father = await this.findChildren(result, (childItem, fatherItem) => {
          // 此处的childItem可能是这个item的父级对象
          if (item[parent.field] == childItem[id]) {
            return true
          }
        }, childField)

        if (father) {
          // 如果是第一次赋值，新增一个children字段
          if (!father[childField]) {
            father[childField] = []
          }
          father[childField].push(item)
          // 排序
          if (father[childField].length > 0 && father[childField][0][sortField] != undefined) {
            father[childField].sort((v1, v2) => v1[sortField] > v2[sortField] ? 1 : -1)
          }
        } else {
          // 找不到这个item的父级，可能是子级顺序在这个父级之前
          tempList.push(item)
        }
      }

      if (lastLen == tempList.length) {
        // 没有弹出过，则抛出
        break
      } else {
        // 有弹出过，刷新数据条数记录，继续遍历剩余的子级
        childList = tempList
        lastLen = childList.length
      }
    }
    this.changeListByNum(outList, tempList)
    return result
  }

  // 根据数值创建数组
  makeList(min, max, value = undefined) {
    const tempList = Array.from({length: max - min + 1}, (_, index) => {
      return value == undefined ? min + index : value
    })
    return tempList
  }

  // 重置为一级结构。
// fatherField：自定义父级字段名（父级对象的参数id值，第一层为undefined）。
// removeChild:是否删除children列表。
// isLastChild：自定义最后一级字段名(Boolean值)
  unlockTree(dataList, id = 'id', childField = 'children',
             fatherField = undefined, removeChild = true, isLastChild = undefined) {
    let result = []

    function _fn(childrenList, fatherId) {
      childrenList.forEach(item => {
        if (item[childField] != undefined && item[childField] instanceof Array) {
          const temp = item[childField]
          if (temp.length <= 0 && isLastChild != undefined) {
            item[isLastChild] = true
          }
          if (removeChild) {
            delete item[childField]
          }
          _fn(temp, item[id])
        } else {
          item[isLastChild] = true
        }

        // 存在自定义父级字段名称
        if (fatherField != undefined) {
          item[fatherField] = fatherId
        }
        result.push(item)
      })
    }

    _fn(dataList, undefined)
    return result;
  }

  // 给树形结构添加表示第几层的字段。levelField：表示层数的字段名
  treeLevel(treeObj, childField = 'children', levelField = 'level') {
    function _add(item, nowLevel) {
      item.forEach(child => {
        let level = nowLevel
        child[levelField] = nowLevel
        if (child[childField] instanceof Array && child[childField].length > 0) {
          _add(child[childField], level + 1)
        }
      })
    }

    _add(treeObj, 0)
  }

  // 将一维变成为二维数组。number：每个包含三个元素
  makeArray(number = 3, ListObj = []) {
    // let level = list[0]
    // let number = list[1]
    let result = []
    // 根据元素数量判断可以生成多少个维数数组
    // let listLength = Math.floor(ListObj.length / number)
    // if ((ListObj.length % number) > 0) {
    //   listLength += 1
    // }
    let outNumber = 0
    while (ListObj.length > outNumber) {
      // 提取元素个数
      const tempList = ListObj.slice(outNumber, outNumber + number)
      result.push(tempList)
      outNumber += number
    }
    return result
  }

  // 判断两个数组的元素都相等，忽视索引位置
  isEqualArray(arr1, arr2) {
    if (arr1.length !== arr2.length) {
      return false;
    }
    const sortedArr1 = arr1.slice().sort(); // 对数组进行排序
    const sortedArr2 = arr2.slice().sort();
    return sortedArr1.every((item, index) => item === sortedArr2[index]);
  }

  // 判断第一个数组包含了第二个数组，忽视索引值。第二数组空会返回true
  isArrayIncludes(arr1, arr2) {
    if (arr1.length < arr2.length) {
      return false;
    }
    return arr2.every(item => arr1.includes(item));
  }

  // 静态，保存原对象内存地址不变，更新指定数量的成员
  changeListByNum(oldList = [], newData = [], number = -1, startIndex = 0) {
    if (number = -1) {
      // 删除全部
      oldList.splice(0, oldList.length)
    } else {
      // 删除指定数
      oldList.splice(startIndex, number)
    }
    oldList.push(...newData)
  }

  // 判断列表里面是否包含对象。字符串时是否转为小写再比较
  includesList(list, obj, toLower = true) {
    let result = false
    list.find(row => {
      let tempObj = obj
      let value = row;
      if (toLower) {
        if (typeof tempObj == 'string') {
          tempObj = obj.toLowerCase()
        }
        if (typeof value == 'string') {
          value = row.toLowerCase()
        }
      }
      if (value == tempObj) {
        result = true
        return true
      }
    })
    return result
  }

  // 根据sku值生成列表。arr：[['a', 'b', 'c'], ['A',], ['1', '2']]。
  // splitStr：分割父，如果为undefined则不进行拼接处理，此时返回的是List<List<object>>
  async skuList(arr = [], splitStr = undefined) {
    let result = []
    if (!arr || arr.length <= 0) {
      return result
    }
    const generateSkuList = async (level, sku) => {
      if (level === arr.length) {
        if (splitStr == undefined) {
          result.push(sku);
        } else {
          result.push(sku.join(splitStr));
        }
        return;
      }

      for (let i = 0; i < arr[level].length; i++) {
        let newSku = [...sku]; // 复制一份 sku 数组，避免修改原数组
        newSku.push(arr[level][i]);
        await generateSkuList(level + 1, newSku);
      }
    }

    await generateSkuList(0, []);


    // 结果为：["a;A;1","a;A;2",...]
    return result;
  }

  // 融合数值区间：[[1,3],[2,5],[7,10]] => [[1,5],[7,10]]
  numberAssign(intervals) {
    // Step 1: 按照起始位置排序
    intervals.sort((a, b) => a[0] - b[0]);

    // Step 2: 创建结果列表
    let merged = [];

    // Step 3: 遍历排序后的原始列表
    for (let interval of intervals) {
      // Step 4: 判断是否相交
      if (!merged.length || interval[0] > merged[merged.length - 1][1]) {
        merged.push(interval);
      } else {
        // Step 5: 更新最后一个区间的结束位置
        merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], interval[1]);
      }
    }

    return merged;
  }

}

const listUtil = new ListUtil()

class StringUtil {

  // 字符串或数组去重复元素
  removeSame(Obj) {
    if (typeof Obj === 'string') {
      const text = new Set(Obj)
      return [...text].join('')
    } else if (Obj instanceof Array) {
      return Array.from(new Set(Obj))
    } else {
      return Obj
    }
  }

  // region 取字符串中间
  /*
  *   str:被取字符串
  *   strBefore:前字符串
  *   strAfter:后字符串
  *   False:失败时返回的字符串
  *   return：返回string
  * */
  getStrCenter(str, strBefore, strAfter, False = undefined, toLower = false) {
    if (str == undefined) {
      return False
    }

    // 保留原有的
    const oldStr = str;
    if (toLower) {
      str = str.toLowerCase()
      strBefore = strBefore.toLowerCase()
      strAfter = strAfter.toLowerCase()
    }
    try {
      let before = str.indexOf(strBefore);
      let after = str.indexOf(strAfter, before + strBefore.length);
      if (before == -1 || after == -1) {
        return False
      } else {
        return oldStr.slice(before + strBefore.length, after)
      }
    } catch (err) {
      return False
    }
  }

  // endregion

  // region 取文本中间2。倒找（右边）strBefore文本，然后根据那位置左边开始找strAfter
  getStrCenterR(str, strBefore, strAfter, False = undefined, toLower = false) {
    if (str == undefined) {
      return False
    }
    const oldStr = str;
    if (toLower) {
      str = str.toLowerCase()
      strBefore = strBefore.toLowerCase()
      strAfter = strAfter.toLowerCase()
    }
    try {
      let before = str.lastIndexOf(strBefore);
      let after = str.indexOf(strAfter, before + strBefore.length);
      if (before == -1 || after == -1) {
        return False
      } else {
        return oldStr.slice(before + strBefore.length, after)
      }
    } catch (err) {
      return False
    }
  }

  // endregion

  // region 取指定文本左边
  getStrLeft(str, strAfter, False = undefined, toLower = false) {
    if (str == undefined) {
      return False
    }
    const oldStr = str;
    if (toLower) {
      str = str.toLowerCase()
      strAfter = strAfter.toLowerCase()
    }
    try {
      let after = str.indexOf(strAfter);
      if (after == -1) {
        return False
      }
      return oldStr.slice(0, after)
    } catch (err) {
      return False
    }
  }

  // endregion

  // region 倒数，取指定文本右边
  getStrRightR(str, strBefore, False = undefined, toLower = false) {
    if (str == undefined) {
      return False
    }
    const oldStr = str
    if (toLower) {
      str = str.toLowerCase()
      strBefore = strBefore.toLowerCase()
    }
    try {
      let before = str.lastIndexOf(strBefore);
      if (before == -1) {
        return False
      }
      return oldStr.slice(before + strBefore.length)
    } catch (err) {
      return False
    }
  }

  // endregion


  // 判断两个文本是否相对，是否转为小写再比较
  equalStr(str1, str2, str1Lower = true, str2Lower = true) {
    let tempStr1 = String(str1)
    let tempStr2 = String(str2)
    if (str1Lower) {
      tempStr1 = tempStr1.toLowerCase()
    }
    if (str2Lower) {
      tempStr2 = tempStr2.toLowerCase()
    }
    return tempStr1 == tempStr2
  }

}

const stringUtil = new StringUtil()

const dateWeek = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']

// 日期对象
class MyDate {
  // 获取两个区间的日期范围。toUp：多出时分秒时是否进一
  static inList(startObj, endObj, toUp = false) {
    let result = []
    const startDate = new MyDate(startObj)
    const endDate = new MyDate(endObj)
    let one = startDate
    let two = endDate
    // 获取相差多少天
    let number = endDate.thanNum(startObj, 'd')
    // 第二个大于第一个
    if (number < 0) {
      one = endDate
    }
    // 绝对值
    number = Math.abs(number)
    // 如果多出了时分，进一
    if (toUp) {
      number = Math.ceil(number)
    }
    result.push(one.toString())
    for (let i = number - 1; i >= 0; i--) {
      one.editDate(1, 'date')
      result.push(one.toString())
    }
    return result
  }

  // 融合时间区间列表
  static assign(dateRanges = []) {
    if (dateRanges.length <= 0) {
      return []
    }
    let newRanges = newObj(dateRanges)
    // 将区间转为数值
    newRanges.forEach(row => {
      let one = new MyDate(row[0])
      let two = new MyDate(row[1])
      row[0] = one.number
      row[1] = two.number
    })
    // 合并区间
    newRanges = listUtil.numberAssign(newRanges)
    // 再转换日期
    newRanges.forEach(row => {
      let one = new MyDate(row[0])
      let two = new MyDate(row[1])
      row[0] = one.toString()
      row[1] = two.toString()
    })

    return newRanges;
  }

  // 当前时间的MyDate对象
  static get nowMyDate() {
    return new MyDate(MyDate.getNow)
  }

  // 当前日期
  static get getNow() {
    return new Date();
  }

  // obj：日期对象或者"字符串"
  constructor(obj, splitStr = "-", hourSplit = ":") {
    this._init(obj, splitStr, hourSplit)
  }

  _init(obj, splitStr = "-", hourSplit = ":") {
    if (typeof obj == "string") {
      let year = stringUtil.getStrLeft(obj, splitStr, obj)
      let month = stringUtil.getStrCenter(obj, splitStr, splitStr, obj)
      let day = stringUtil.getStrRightR(obj, splitStr, obj)
      let hours = stringUtil.getStrCenter(obj, " ", hourSplit, 0)
      let minutes = stringUtil.getStrCenter(obj, hourSplit, hourSplit, 0)
      let seconds = stringUtil.getStrRightR(obj, hourSplit, 0)
      this.dateObj = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hours), parseInt(minutes), parseInt(seconds))
    } else {
      this.dateObj = new Date(obj)
    }

    // 时间戳
    this.number = this.dateObj.getTime()

    // 日期
    this.year = this.dateObj.getFullYear()
    this.month = this.dateObj.getMonth() + 1
    this.monthStr = String(this.month).padStart(2, '0')
    this.date = this.dateObj.getDate()
    this.dateStr = String(this.date).padStart(2, '0')

    // 星期几，时分秒
    this.day = this.dateObj.getDay()
    this.hours = this.dateObj.getHours()
    this.hoursStr = String(this.hours).padStart(2, '0')
    this.minutes = this.dateObj.getMinutes()
    this.minutesStr = String(this.minutes).padStart(2, '0')
    this.seconds = this.dateObj.getSeconds()
    this.secondsStr = String(this.seconds).padStart(2, '0')
  }

  // 获取星期
  getWeek() {
    return dateWeek[this.day]
  }


  // 格式化
  toString(splitStr = '-', hourSplit = ':', back = 'both') {
    // 只需要返回的对象，解决前两个参数没办法接受undefined
    if (back != 'both') {
      if (back == 'year') {
        hourSplit = undefined
      } else if (back == 'hour') {
        splitStr = undefined
      }
    }
    let date = ""
    let hourS = ""
    if (splitStr != undefined) {
      date = `${this.year}${splitStr}${this.monthStr}${splitStr}${this.dateStr}`
    }
    if (hourSplit != undefined) {
      hourS = `${this.hoursStr}${hourSplit}${this.minutesStr}${hourSplit}${this.secondsStr}`
      if (splitStr != undefined) {
        hourS = ` ${hourS}`
      }
      date += hourS
    }
    return date
  }

  // 值获取日期
  toStringYear(hourValue = "", splitStr = "-") {
    let tempResult = this.toString(splitStr, ":", 'year')
    if (hourValue?.length > 0) {
      return `${tempResult} ${hourValue}`
    } else {
      return tempResult
    }
  }

  // 值取时间
  toStringHour(yearValue = "", splitStr = ":") {
    let tempResult = this.toString('-', splitStr, 'hour')
    if (yearValue?.length > 0) {
      return `${yearValue} ${tempResult}`
    } else {
      return tempResult
    }
  }

  // 比较大小，大于返回2，等于返回1，小于返回0
  thanBig(dateObj) {
    let newDate = new MyDate(dateObj)
    if (this.number > newDate.number) {
      return 2
    } else if (this.number == newDate.number) {
      return 1
    } else {
      return 0
    }
  }

  // 只比较日期，忽视时分秒。大于返回2，等于返回1，小于返回0
  thanBigOnlyDate(dateObj) {
    let thisDate = new MyDate(`${this.year}-${this.month}-${this.date}`)
    let tempDate = new MyDate(dateObj)
    let newDate = new MyDate(`${tempDate.year}-${tempDate.month}-${tempDate.date}`)
    if (thisDate.number > newDate.number) {
      return 2
    } else if (thisDate.number == newDate.number) {
      return 1
    } else {
      return 0
    }
  }

  // 添加或相减
  editDate(num, type = 'year') {
    switch (type) {
        // 年份相加减
      case "year":
        this.dateObj.setFullYear(this.year + num)
        break
      case 'month':
        this.dateObj.setMonth(this.month - 1 + num)
        break
      case 'date':
        this.dateObj.setDate(this.date + num)
        break
      case 'hours':
        this.dateObj.setHours(this.hours + num)
        break
      case 'minutes':
        this.dateObj.setMinutes(this.minutes + num)
        break
      case 'seconds':
        this.dateObj.setSeconds(this.seconds + num)
        break
    }
    this._init(this.dateObj)
    return this
  }

  // 设置时分秒
  editHour(hours = "23:59:59") {
    let tempStr = this.toString("-", ":", "year") + ' ' + hours
    this._init(tempStr)
    return this
  }

  // 取这个月的天数
  getLength() {
    const tempObj = new MyDate(`${this.year}-${this.month + 1}-0`)
    return tempObj.dateObj.getDate();
  }

  // 遍历这个月。回调函数接受三个参数：第一个是当天的MyDate对象，第二个是日期，第三个是星期几
  forEach(callback) {
    const tempList = listUtil.makeList(1, this.getLength())
    tempList.forEach(item => {
      const tempDate = new MyDate(`${this.year}-${this.month}-${item}`)
      if (typeof callback == "function") {
        callback(tempDate, item, tempDate.getWeek())
      }
    })
  }

  // 获取本周（1到7）的信息。sunday是否已星期天为第一天
  getWeekList(sunday = true) {
    const dateList = []
    // 获取后面天数。
    let lastNum = 6 - this.day
    if (!sunday) {
      lastNum = 7 - this.day
    }
    if (lastNum > 0) {
      let thisNum = 1
      while (lastNum >= thisNum) {
        const tempNewDate = new MyDate(this.dateObj)
        tempNewDate.editDate(thisNum, 'date')
        dateList.push(tempNewDate.toString())
        thisNum += 1
      }
    }
    // 今天
    dateList.unshift(this.toString())
    // 获取前面的天数。例如前面有5天
    let beforeNum = this.day - 0
    if (beforeNum > 0) {
      while (beforeNum != 0) {
        beforeNum -= 1
        const tempNewDate = new MyDate(this.dateObj)
        tempNewDate.editDate(beforeNum - this.day, 'date')
        dateList.unshift(tempNewDate.toString())
      }
    }
    if (!sunday) {
      dateList.shift()
    }
    return dateList
  }

  // 相隔多少。已什么为单位
  thanNum(dateObj, type = "s") {
    let newDate = new MyDate(dateObj)
    // 是否大于
    let isBig = true
    if (this.number <= newDate.number) {
      isBig = false
    }

    // 时间戳相差
    const thanNumber = Math.abs(this.number - newDate.number)

    // 计算单位
    let result = 0
    switch (type) {
      case 'd':
        result = thanNumber / (24 * 60 * 60 * 1000)
        break
      case 'h':
        result = thanNumber / (60 * 60 * 1000)
        break
      case 'm':
        result = thanNumber / (60 * 1000)
        break
      case 's':
        result = thanNumber / 1000
        break
      case 'mi':
        result = thanNumber
        break;
    }

    // 直接舍弃3位小数之后的后面值
    result = Math.floor(result * 1000) / 1000

    return isBig ? result : -result
  }

}

// endregion

const dateObj = ref({})
const nowDate = ref('')
watch(() => props.modelValue, (newV, oldV) => {
  if (newV) {
    dateObj.value = new MyDate(newV)
    nowDate.value = dateObj.value.dateObj
  } else {
    dateObj.value = MyDate.nowMyDate
    nowDate.value = MyDate.nowMyDate.dateObj
  }
}, {immediate: true, deep: true})

watch(() => nowDate.value, (newV, oldV) => {
  dateObj.value = new MyDate(newV)
  emit('update:modelValue', dateObj.value.toString())
}, {immediate: true, deep: true})

</script>

<style scoped lang='scss'>
.calendarX {
  height: 100%;
  width: 100%;
  position: relative;
}

.headerBox {
  display: flex;
  justify-content: space-between;
  width: 100%;

  .left {
    flex: 1 1 auto;
  }

  .center {
    flex: 0 0 auto;
  }

  .right {
    flex: 1 1 auto;
    text-align: right;
  }
}
</style>